package com.neusoft.bizcore.notice.notification.util;

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;

import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Service;

import com.neusoft.bizcore.notice.notification.dto.NoticeTemplateAttachmentDTO;
import com.neusoft.bizcore.notice.notification.dto.NoticeTemplateDTO;
import com.neusoft.bizcore.notice.notification.service.NoticeTemplateService;

import freemarker.cache.TemplateLoader;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@DependsOn("applicationContextProvider")
@Service
public class DatabaseTemplateLoader implements TemplateLoader {

    private final NoticeTemplateService noticeTemplateService;

    public DatabaseTemplateLoader() {
        this.noticeTemplateService = ApplicationContextProvider.getBean(NoticeTemplateService.class);
    }

    @Override
    public Object findTemplateSource(final String name) throws IOException {
        try {

            // 模板名称后边会自动加入_zh_CN字符串，需要去掉。
            final String pattern = "_zh_CN";
            final String[] result = name.split(pattern);

            final NoticeTemplateDTO noticeTemplate = this.noticeTemplateService.findByType(result[0]);

            final NoticeTemplateAttachmentDTO attachment = noticeTemplate.getTemplate();

            // 数据库表必须有一个最后更新字段用来刷新缓存
            return new StringTemplateSource(name, new String(attachment.getTemplate()),
                    attachment.getUpdateTime().getTime());
        } catch (final Exception e) {
            DatabaseTemplateLoader.log.error("查找模板源失败", e);
            return null;
        }
    }

    @Override
    public long getLastModified(final Object templateSource) {
        return ((StringTemplateSource) templateSource).lastModified;
    }

    @Override
    public Reader getReader(final Object templateSource, final String encoding) throws IOException {
        return new StringReader(((StringTemplateSource) templateSource).source);
    }

    @Override
    public void closeTemplateSource(final Object templateSource) throws IOException {
        // TODO Auto-generated method stub

    }

    private static class StringTemplateSource {
        private final String name;
        private final String source;
        private final long lastModified;

        StringTemplateSource(final String name, final String source, final long lastModified) {
            if (name == null) {
                throw new IllegalArgumentException("name == null");
            }
            if (source == null) {
                throw new IllegalArgumentException("source == null");
            }
            if (lastModified < -1L) {
                throw new IllegalArgumentException("lastModified < -1L");
            }
            this.name = name;
            this.source = source;
            this.lastModified = lastModified;
        }

        @Override
        public boolean equals(final Object obj) {
            if (obj instanceof StringTemplateSource) {
                return this.name.equals(((StringTemplateSource) obj).name);
            }
            return false;
        }

        @Override
        public int hashCode() {
            return this.name.hashCode();
        }

    }

    @Override
    public String toString() {
        return this.toString();
    }
}
